import React, {
  PropsWithChildren,
  useCallback,
  useContext,
  useEffect,
} from "react";
import { Form, Input, Checkbox } from "antd";
import update from "immutability-helper";
import FunFormCtx from "../../core";
import { FormInstance } from "rc-field-form";

const useFunFormsetting = () => {
  const { instance, updateInstance } = useContext(FunFormCtx);

  const updateWidget = useCallback(
    (
      { groupIndex, cardIndex, rowIndex, colIndex }: ActivedElementAt,
      newWidget: FunFormWidget
    ) => {
      const oldWidget =
        instance.groups[groupIndex].cards[cardIndex].rows[rowIndex].columns[
          colIndex
        ].widget;

      updateInstance(
        update(instance, {
          groups: {
            [groupIndex]: {
              cards: {
                [cardIndex]: {
                  rows: {
                    [rowIndex]: {
                      columns: {
                        [colIndex]: {
                          widget: {
                            $set: { ...oldWidget, ...newWidget },
                          },
                        },
                      },
                    },
                  },
                },
              },
            },
          },
        })
      );
    },
    [instance, updateInstance]
  );
  return {
    updateWidget,
  };
};

const { Item: FormItem } = Form;

export const CommonItem = ({ form }: { form: FormInstance }) => {
  return (
    <React.Fragment>
      <FormItem
        label="关联字段"
        required
        rules={[
          {
            type: "method",
            validator(_: any, value: string) {
              if (!value) return Promise.reject("请录入字段名（英文）");
              const reg = /^[a-zA-Z][a-zA-Z0-9_]*$/;
              if (reg.test(value)) return Promise.resolve(value);
              return Promise.reject(
                "请键入正确的字段名称（字母开头、包含字母、下划线、数字）"
              );
            },
          },
        ]}
        name="name"
      >
        <Input placeholder="输入字段" />
      </FormItem>
      <FormItem noStyle shouldUpdate={(p, n) => p.hidelabel !== n.hidelabel}>
        {({ getFieldValue }) => {
          const isHideLabel = getFieldValue("hidelabel");
          if (!isHideLabel) {
            return (
              <FormItem
                label="标题"
                required
                name="label"
                rules={[
                  {
                    required: true,
                    message: "请输入标题",
                  },
                ]}
              >
                <Input placeholder="请输入标题" />
              </FormItem>
            );
          }
          return <React.Fragment></React.Fragment>;
        }}
      </FormItem>
      <FormItem name="hidelabel" valuePropName="checked">
        <Checkbox
          onChange={({ target: { checked } }) => {
            const checkedValue = form.getFieldValue("hidelabel");
            form.setFieldsValue({
              hidelabel: checked ? checkedValue : undefined,
            });
            form.submit();
          }}
        >
          隐藏标题
        </Checkbox>
      </FormItem>
      <FormItem label="占位符/空提示" name="placeholder">
        <Input />
      </FormItem>
      <FormItem label="是否必填" valuePropName="checked" name="isRequired">
        <Checkbox
          onChange={({ target: { checked } }) => {
            form.setFieldsValue({ isRequired: checked });
            form.submit();
          }}
        ></Checkbox>
      </FormItem>
    </React.Fragment>
  );
};

const WidegetWrap = (
  props: PropsWithChildren<
    ActivedElemnetType<FunFormWidget> & { withBase?: boolean }
  >
) => {
  const { element, position, children, withBase = true } = props;
  const { updateWidget } = useFunFormsetting();

  const [form] = Form.useForm<FunFormWidget>();

  useEffect(() => {
    form.setFieldsValue(element);
  }, [element, form]);

  const update = useCallback(() => {
    form
      .validateFields()
      .then((value: FunFormWidget) => {
        updateWidget(position, value);
      })
      .catch(() => {});
  }, [form, position, updateWidget]);

  return (
    <Form
      form={form}
      layout="vertical"
      initialValues={element}
      onFinish={update}
      onChange={update}
    >
      {withBase && <CommonItem form={form}></CommonItem>}
      {typeof children == "function" ? children(form) : children}
    </Form>
  );
};

export default WidegetWrap;
